Spec_iGEM_Calc.R<-function(){}
 
#to stop all stop(text,call.=T)
iGEM_Calc_LoadLibrary <- function() { ##FINAL
  #load libraries
  lib <- c("ggplot2","bio3d","ape","seqinr","apTreeshape","phyclust","tcltk")
  for (i in 1:length(lib)) {
    if(!(paste0("package:",lib[i],sep="") %in% search())){
      if(!require(lib[i],character.only=T)){
        if(!isTRUE(install.packages(lib[i]))){print(paste("Please install the package per 'R CMD INSTALL':",lib[i]))}
      }
    }
  }  
} 

Calc_LoadLibrary()
Spec_iGEM_Calc.R<-function(){} 

###possible interaction/binding sites between two pdb files (single chained or with ligand)
igem_BindSite<-function(pdb.a=NULL,pdb.b=NULL,a.inds=NULL,b.inds=NULL,cut=5,hydrogens=T,objective.text=T){
  if((is.null(pdb.a))|(is.null(pdb.b))){
    cat("Error: Please use two PDB files, even if they're the same.")
    return(visible(NULL))
  }else if(is.null(pdb.a)|is.null(pdb.b)){
    
    cat("Error: Please use always (if already available) all information about 'i.inds'.")
    return(visible(NULL))
    
  }else if ((try(a.inds<-igem_core_analysis(pdbs=pdb.a,Name=Name,save_inds=F)))&&(try(b.inds<-igem_core_analysis(pdbs=pdb.b,Name=Name,save_inds=F)))){
    bd<-bio3d::binding.site(pdb.a,pdb.b,a.inds,b.inds,cut,hydrogens)      
    return(bd)      
  }else{
    cat("Error: Please check your PDB files, so they just contain a single chain to calculate 'i.inds'.")
    return(visible(NULL))
  }    
}

### Data can befasta or PDBs
#use multiple pdbs as "PDBs"
igem_pdbs_heat<-function(PDBs=NULL,ids=NULL,seq.ident=F,Name=""){ 
  #inside
  save_SeqIdent<-function(pdbs=NULL,seq.ident=F){
    if(seq.ident){
      m.seq.ident<-bio3d::seqidentity(pdbs)
      FileName<-paste0(Name,"SequenceIdentity.csv",collapse=NULL)
      write.table(m.seq.ident,file= FileName)
      SaveHeat(m.seq.ident,paste0(Name,"SequenceIdentity",collapse=NULL),ids,ids)      
    }
  }
  #script
  if(!is.null(PDBs)){    
    pdbs<-bio3d::pdbaln(PDBs)
    Save_SeqIdent(pdbs,seq.ident)
    return(pdbs)
  }else if(is.null(ids)){
    cat("Error: Use representing ids while not providing pdb files.")
    return(invisible(NULL))
  }else{
    #download
    raw.files<-bio3d::get.pdb(ids,path="raw_pdbs")
    files<-bio3d::pdbsplit(raw.files,ids) #characte vector
    #alignment
    pdbs<-bio3d::pdbaln(files)    
    Save_SeqIdent(pdbs,seq.ident)
    return(pdbs)
  }
}

igem_pdb_rmsd<-function(pdbs=NULL,Name="",save=T){
  if(!is.null(pdbs)){
    m.rmsd<-bio3d::rmsd(pdbs,fit=T)
    if(save){
      FileName<-paste0(Name,"_rmsd.csv",collapse=NULL)
      write.table(m.rmsd,file=FileName )
      SaveHeat(m.rmsd,paste0(Name,"_rmsd",collapse=NULL),ids,ids)
    }
    return(m.rmsd)
  }else{
    cat("Error: Provide one or more pdb files.")
  }
}

#testing is necessary !!!
#if used on multiple do superposition first
igem_core_analysis<-function(pdb=NULL,Name="",save_core=c("black","pink","red"),plot_inds=T,save_inds=T){
  if (!is.null(pdb)){
    core<-bio3d::core.find(pdb) 
    if(plot_inds){
      col<-rep(save_core[1],length(core$volume))
      col[core$volume<2]=save_core[2]
      col[core$volume<1]=save_core[3]
      FileNamePre<-paste0(Name,"_CoreSize.png",collapse=NULL)
      png(filename = FileNamePre, width = 1500, height = 780)
      print(plot(core,col=col))
      dev.off()
    }
    #core sizeagainst total ellipsoidresidue
    core.inds<-print(core,vol=1)
    if(save_inds){ 
      FileNamePre<-paste0(Name,"_quickCore.pdb",collapse=NULL)
      bio3d::write.pdb(xyz=pdbs$xyz[1,core.inds$xyz],file=FileNamePre)
    }
    core.inds<-print(core)
    return(core,core.inds)
  }else{
    cat("Error: Please provide one or an superpositioned pdb file.")
    return(invisible(NULL))    
  }
} 

igem_superposition<-function(pdbs=NULL,core.inds=NULL,out=getwd()){
  
  if (!is.null(pdbs)){
    if(!is.null(core.inds)){
      xyz<-bio3d::pdbfit(pdbs,core.inds,outpath=out)
      return(xyz)
    }else if( !is.null(try((core.inds<-(igem_core_analysis(pdb=pdbs[[1]],Name=NULL,save_inds=F,plot_inds=F))[2])) )){
      xyz<-bio3d::pdbfit(pdbs,core.inds,outpath=out)
      return(xyz)      
    }else{
      cat("Error: Provide an useful 'core.inds'.")
      return(invisible(NULL))
    }
  }else{
    cat("Error: Provide one ore more pdbs.")
    return(invisible(NULL))
  }
}

#on one pdb or multiple pdbs
igem_get_gaps<-function(pdbs=NULL){ #pca pre processing
  if(is.null(pdbs)){ 
    if(try({gaps.res<-bio3d::gap.inspect(pdbs$ali[1,])
            gaps.pos<-bio3d::gap.inspect(pdbs$xyz[1,])      
    })){
      return(c(gaps.res,gaps.pos)) 
    }else{
      cat("Error: No good pdb file was provided.")
    }
  }else{
    cat("Error: Provide one ore more pdb files.")
    return(invisible)
  }
}

igem_rmsd<-function(pdbs=NULL,xyz=NULL,Name="",save=T){ #of supersposition and normal
  #inside
  frmsd_save<-function(rd=NULL,save=T,Name=""){
    if(save){
      FileNamePre<-paste0(Name,"_RMSD|2D.png",collapse=NULL)
      png(filename = FileNamePre, width = 1500, height = 780)
      print({hist(rd,breaks=variation_span(rd),xlab="RMSD (A)")
             lines(density(rd),col="gray",lwd=3)})
      dev.off()
    }
  }  
  #script  
  if(!is.null(xyz)){
    rd<-bio3d::rmsd(xyz)
    frmsd_save(rd,save,Name)
    return(rd)
  }else if(is.null(pdbs)){
    cat("Error: Provide one or more pdb files.")
    return(invisible(NULL))
  }else{
    #if pdbs are list
    core<-igem_core_analysis(pdbs[[1]],Name,save_core=c("black","pink","red"),plot_inds=T,save_inds=T)
    xyz<-igem_superposition(pdbs,core.inds=core[2],out=getwd())
    rd<-bio3d::rmsd(xyz)
    frmsd_save(rd,save,Name)
    return(rd)
  } 
}  

igem_rmsd_clust<-function(pdbs=NULL,rd=NULL,Name="",save=T,lab=NULL){#Clustering
  #inside
  frmsd_clust_save<-function(hc.rd=NULL,pbds=NULL,save=T,lab=NULL){
    if(save){
      if(is.null(pdbs)){
        lab=pdbs$id
        cat("Warning: Provide an existing pdb file for better annotation.")
      }else{
        lab=lab
      }
      FileNamePre<-paste0(Name,"_hClust.png",collapse=NULL)
      png(filename = FileNamePre, width = 1500, height = 780)
      print(plot(hc.rd,labels=lab,ylab="RMSD",main="RMSD Cluster Dendrogram")) 
      dev.off()
    }
  }  
  #script
  if(!is.null(rd)){
    hc.rd<-stats::hclust(as.dist(rd))
    frmsd_clust_save<-function(hc.rd=hc.rd,pbds=pdbs,save=save,lab)
      return(hc.rd)
  }else{
    if(is.null(pdb)){
      cat("Error: Provide rmsd or pdb for clustering.")
      return(invisible(NULL))
    }else{
      rd<-igem_rmsd(pdbs=pdbs,xyz=NULL,Name="",save=F)
      hc.rd<-stats::hclust(as.dist(rd))
      frmsd_clust_save<-function(hc.rd=hc.rd,pbds=pdbs,save=save,lab)
        return(hc.rd)
    }
  } 
}

igem_dendogramm<-function(dist.clust=NULL,pdbs=NULL,ids=NULL,ylab="",Name="",main="",h=NULL){
  #inside
  save_dend<-function(hc=NULL,ids=NULL,Name="",ylab="",main="",h=NULL){
    dend <- as.dendrogram(hc)
    #names(col)<-ids
    colLab<-ids
    #names(cols) <- pdbs$id
    op <- par(no.readonly = TRUE)
    par(cex = 0.8)
    dend_colored <- dendrapply(dend, colLab, col)
    
    if(is.null(h)){h<-30} #default value
    
    FileNamePre<-paste0(Name,"_hClust.png",collapse=NULL)
    png(filename = FileNamePre, width = 1500, height = 780) 
    
    print({plot(dend_colored, cex.axis = 1.2, cex.lab = 1.2, cex.main = 1.2, ylab = ylab, main = main)
           abline(h = h, lty = 3, col = "gray60")})
    
    dev.off()
    
    return(dend)
  }
  
  #script
  if(!is.null(dist.clust)){##here no distance vector
    # 
    if(is.null(ids)){
      if(is.null(pdbs)){
        cat("Warning: Use ids or pdbs for a better annotation ")
      }
      dend<-save_dend(hc=dist.clust,ids=ids,Name=Name,ylab=ylab,main=main,h=h)
      return(dend)
    }else{
      dend<-save_dend(hc=dist.clust,ids=ids,Name=Name,ylab=ylab,main=main,h=h)
      return(dend)
    }   
    
    dend<-save_dend(hc=dist.clust,ids=ids,Name=Name,ylab=ylab,main=main,h=h)
    
    return(dend) 
  }else{ #NO sdistance
    if(is.null(pdbs)){      
      cat("Error: Whether pdb file nor distance clustering was distributed.")
      return(invisible(NULL))  
    }else{
      #pdbs!!! 
      core<-igem_core_analysis(pdbs[[1]],Name,save_core=c("black","pink","red"),plot_inds=F,save_inds=F)
      xyz<-igem_superposition(pdbs,core.inds=core[2],out=getwd())
      rd<-igem_rmsd(pdbs=pdb,xyz=xyz,Name=Name,save=F)
      hc.rd<-igem_rmsd_clust(pdbs=pdbs,rd=rd,Name=Name,save=F)
      ids<-pdbs$ids
      dist.clust<-igem_rmsd_clust(pdbs=pdbs,rd=rd,Name=Name,save=F)
      dend<-save_dend(hc=dist.clust,ids=ids,Name=Name,ylab="",main="",h=h)
      return(dend)
    }
  } 
}


#RMSF ????
igem_rmsf<-function(pdbs=NULL,xyz=NULL,res.inds=NULL,gaps.pos=NULL,sse=NULL,save=T){
  #inside
  save_rmsf<-function(res.ind=NULL,rf=NULL,sse=NULL,save=T){
    if(save){
      FileNamePre<-paste0(Name,"_RMSF|2D.png",collapse=NULL)
      png(filename = FileNamePre, width = 1500, height = 780)
      print(plot.bio3d(res.ind,rf,sse=sse,ylab="RMSF (A)",xlab="Position",typ="l"))
      dev.off()
    }
  }
  #script  
  
  if(!is.null(xyz)){
    if(is.null(res.ind)){gap.pos<-igem_get_gaps(pdbs=pdbs)[2]}
    if(is.null(gaps.pos)){res_inds<-igem_core_analysis(pdb=pdbs,Name=Name,save_core=c("black","pink","red"),plot_inds=F,save_inds=F)[2]}
    if(is.null(sse)){sse<-igem_sec_struct(pdb=pdbs,name=Name)}
    if(try(rf<-bio3d::rmsf(xyz[,gaps.pos$f.ids]))){
      save_rmsf(res.ind,rf,sse,save)
      return(rf)
    }else{
      cat("Error: Provide better variables")
      return(invisible(NULL))
    }    
  }else{#xyz
    if(!is.null(pdbs)){
      gap.pos<-igem_get_gaps(pdbs=pdbs)[2]
      res_inds<-igem_core_analysis(pdb=pdbs,Name=Name,save_core=c("black","pink","red"),plot_inds=F,save_inds=F)[2]
      sse<-igem_sec_struct(pdb=pdbs,name=Name)
      rf<-bio3d::rmsf(xyz[,gaps.pos$f.ids])
      save_rmsf(res.ind,rf,sse,save)
      return(rf)
    }else{
      cat("Error: Provide one or more pdb files.")
      return(invisible(NULL))
    }    
  } 
}   
 
igem_TorDih<-function(pdb=NULL,Name="",save=T){ #Ramachndran plot maybe not multipel pdbs ...
  if(try(tor <- bio3d::torsion.pdb(pdb))){
    FileNamePre<-paste0(Name,"_Ramachndran.png",collapse=NULL)
    png(filename = FileNamePre, width = 1500, height = 780)
    print(plot(tor$phi,tor$psi,xlab="phi",ylab="psi"))
    dev.off()   
  }else{
    cat="Error: Provide an useful pdb file."
  }
}

igem_sec_struct<-function(pdb=NULL,name=NULL){##struct of one pdb
  if(!is.null(pdb)){
    pdb.file<-pdb
  }else if(!is.null){
    if(try(pdb.file<-read.pdb(toupper(name)))){
      #
    }
    else if(try(pdb.file<-read.pdb(toupper(name)))){
      #
    }
    else{cat("Error: Can't find PDB with given name.")}
    
  }else{cat("Error: Use PDB or the name of that file.")}
  sse2<-bio3d::dssp(pdb.file)
  return(sse2)  
}

#mean and standard deviation possible
#mean if pdb.b is provided
igem_calpha_ps_torsion<-function(pdbs,pdb.b=NULL,pdb.name="",name.a="",name.b="",plot=F,Name){
  v.tor<-NULL
  #Mean calpha pseudo-torsion angles  
  if (!is.null(pdb.b)){ ###pdb.b not initialized <- just pdbs => set sd of angle of multiple pdb file
    ##standard deviation instead of difference while using multiple pdb files
    m.xyz<-NULL
    m.x<-NULL
    m.y<-NULL
    m.z<-NULL
    sd.xyz<-NULL
    
    for (i in 1:length(pdbs)){
      m.xyz<-matrix(pdbs$xyz[i,],ncol=3) 
      m.x<-cbind(m.x,m.xyz[i,1])  
      m.y<-cbind(m.y,m.xyz[i,2])  
      m.z<-cbind(m.z,m.xyz[i,3])      
    }
    m.x<-apply(m.x,1,sd) #sd over row <- vector of numerics
    m.y<-apply(m.y,1,sd)
    m.z<-apply(m.z,1,sd)
    for (i in 1:length(pdbs)){
      sd.xyz<-cbind(sd.xyz,m.x[i],m.y[i],m.z[i])      
    }
    sd.xyz<-as.vector(sd.xyz)     
    
    gaps.xyz<-bio3d::is.gap(pdbs$xyz[1,])
    gaps.res<-bio3d::is.gap(pdbs$ali[1,])
    
    resno<-pdbs$resno[,!gaps.res]
    
    v.tor<-bio3d::wrap.tor(bio3d::torsion.xyz(sd.xyz[!gaps.xyz,atm.inc=1]))
    sse2<-igem_sec_struct(pdb=pdbs[1])
    
    if (plot){
      FileNamePre<-paste0(Name,"_Tor_sd.png",collapse=NULL)
      png(filename = FileNamePre, width = 1500, height = 780)
      #plot.dmat()
      print(plot.bio3d(resno,abs(v.tor),typ="h",sse=sse2,xlab="Residue",ylab="Angle"))
      dev.off()     
    }    
    
  }else{
    #if pdbs is single
    if(name.a==""){a.xyz<-pdbs$xyz[1,]
                   gaps.xyz<-bio3d::is.gap(pdbs$xyz[1,])
                   gaps.res<-bio3d::is.gap(pdbs$ali[1,])
                   resno<-pdbs$resno[1,!gaps.res]
    }else{
      a.xyz<-pdbs$xyz[name.a,]
      gaps.xyz<-bio3d::is.gap(pdbs$xyz[name.a,])
      gaps.res<-bio3d::is.gap(pdbs$ali[name.a,])
      resno<-pdbs$resno[name.a,!gaps.res]
    }
    if(name.b==""){
      b.xyz<-pdbs$xyz}  
    else{
      b.xyz<-pdbs$xyz[name.b,]}  
    
    a<-bio3d::torsion.xyz(a.xyz[!gaps.xyz,atm.inc=1])
    b<-bio3d::torsion.xyz(b.xyz[!gaps.xyz,atm.inc=1])
    v.tor<-bio3d::wrap.tor(a-b)
    sse2<-igem_sec_struct(pdb=pdbs[[1]])
    
    if (plot){
      FileNamePre<-paste0(Name,"_Tor_diff.png",collapse=NULL)
      png(filename = FileNamePre, width = 1500, height = 780)
      #plot.dmat()
      print(plot.bio3d(resno,abs(v.tor),typ="h",sse=sse2,xlab="Residue",ylab="Angle"))
      dev.off()     
    }
    
  }          
  
  return(v.tor)
}

#get matrix of distance calculation
igem_dist_MatrixAnalyse<-function(pdbs,pdb.b=NULL,pdb.name="",name.a="",name.b="",plot=F,lab=c(),Name){
  v.dist<-NULL
  #Mean calpha pseudo-torsion angles  
  if (!is.null(pdb.b)){ ###pdb.b not initialized <- just pdbs => set sd of angle of multiple pdb file
    ##standard deviation instead of difference while using multiple pdb files
    i.xyz<-NULL
    dm.xyz<-NULL
    m.xyz<-NULL
    
    for (i in 1:length(pdbs)){
      i.xyz<-cbind(i.xyz,pdbs$xyz[i,])   #as matrix of vector
    }
    
    gaps.xyz<-bio3d::is.gap(pdbs$xyz[1,])
    gaps.res<-bio3d::is.gap(pdbs$ali[1,])
    n.col<-NULL
    for (i in 1:ncol(i.xyz) ){
      dm.xyz<-dm(i.xyz[!gaps.xyz])
      if(is.null(n.col)){n.col<-ncol(dm.xyz)}
      dm.xyz<-melt(m.xyz) #melt matrix to df
      m.xyz<-cbind(m.xyz,dm.xyz$value) #get value into new matrix      
    } #now do sd of all elements
    v.dist<-apply(m.xyz,1,sd)
    v.dist<-matrix(v.dist,nrow=n.col) #get sd matrix over all matrix via apply of last operation      
    
    resno<-pdbs$resno[,!gaps.res]    
    
    if (plot){
      FileNamePre<-paste0(Name,"_DDM_sd.png",collapse=NULL)
      png(filename = FileNamePre, width = 1500, height = 780)
      #plot.dmat()
      print(plot.dmat(v.dist,nlevels=10,grid.col="gray",resnum.1=resno,resnum.2=resno,xlab=lab[1],ylab=lab[2])) 
      dev.off()     
    } 
    
  }else{
    #if pdbs is single
    if(name.a==""){
      a.xyz<-pdbs$xyz[1,]
      gaps.xyz<-bio3d::is.gap(pdbs$xyz[1,])
      gaps.res<-bio3d::is.gap(pdbs$ali[1,])
      resno<-pdbs$resno[1,!gaps.res]
    }else{
      a.xyz<-pdbs$xyz[name.a,]
      gaps.xyz<-bio3d::is.gap(pdbs$xyz[name.a,])
      gaps.res<-bio3d::is.gap(pdbs$ali[name.a,])
      resno<-pdbs$resno[name.a,!gaps.res]
    }
    if(name.b==""){
      b.xyz<-pdbs$xyz}  
    else{
      b.xyz<-pdbs$xyz[name.b,]}  
    
    a<-bio3d::dm(a.xyz[!gaps.xyz])
    b<-bio3d::dm(b.xyz[!gaps.xyz])
    v.dist<-a-b
    
    
    if (plot){
      FileNamePre<-paste0(Name,"_DDM_diff.png",collapse=NULL)
      png(filename = FileNamePre, width = 1500, height = 780)
      #plot.dmat()
      print(plot.dmat(v.dist,nlevels=10,grid.col="gray",resnum.1=resno,resnum.2=resno,xlab=lab[1],ylab=lab[2])) 
      dev.off()     
    }
    
  }          
  
  return(v.dist)
} 

#Sequence based#
igem_conservative<-function(Data=NULL,Name="",save=T){
  if(is.list(Data)|is.matrix(Data)){
    con<-bio3d::conserv(Data,method="similarity",sub.matrix="bio3d") #structural information not just diversity lik in entropy
    if(save){
      FileNamePre<-paste(Name,"_conservative.csv",collapse=NULL,sep="")
      write.table(con,file=FileNamePre,append=FALSE,quote=FALSE,sep=" ", na="NA",dec=".",row.names=TRUE,col.names=TRUE)
      FileNamePre<-paste(Name,"_conservative.png",collapse=NULL,sep="")
      lab=c("Amino Acid Position","Value")
      Save2D_DF(data.frame(con),Name,x_set="",lab=c("Residue","Index"))
    }
    return(con)
  }else{
    cat("Error: Provide a list of alignments.")
    return(invisible(NULL))
  }
}

igem_make.weights<-function(xyz){
  # Calculate pairwise distances
  natoms <- ncol(xyz)/3
  all <- array(0, dim = c(natoms, natoms, nrow(xyz)))
  for (i in 1:nrow(xyz)) {
    dists <- dist.xyz(xyz[i, ])
    all[, , i] <- dists
  }
  
  # Calculate variance of pairwise distances
  all.vars <- apply(all, 1:2, var)
  
  # Make the final weights
  weights <- 1 - (all.vars/max(all.vars))
  return(weights)  
}

igem_consensus_Seq<-function(Data=NULL,Name="",save=T){
  if(is.list(Data)|is.matrix(Data)){
    con<-bio3d::consensus(Data,cutoff=0.6)     
    if(save){
      FileNamePre<-paste(Name,"_consensus.csv",collapse=NULL,sep="")
      write.table(con$seq,file=FileNamePre,append=FALSE,quote=FALSE,sep=" ", na="NA",dec=".",row.names=TRUE,col.names=TRUE)
      col <- mono.colors(32)
      aa  <- rev(rownames(con$freq))
      FileNamePre<-paste(Name,"_confreq.png",collapse=NULL,sep="")
      png(filename = FileNamePre, width = 1500, height = 780)
      print({image(x=1:ncol(con$freq),
                   y=1:nrow(con$freq),
                   z=as.matrix(rev(as.data.frame(t(con$freq)))),
                   col=col, yaxt="n", xaxt="n",
                   xlab="Alignment Position", ylab="Residue Type")
             #axis(side=3, at=c(1:length(con$seq),by=10), labels =con$seq,
             #grid(length(con$seq), length(aa)))) })
             axis(side=1,at=seq(0,length(con$seq),by=10))
             axis(side=2,at=c(1:22),labels=aa)
             axis(side=3,at=c(1:length(con$seq)),labels=con$seq)
             axis(side=4,at=c(1:22),labels=aa)
             grid(length(con$seq),length(aa)) 
      })
      dev.off()
    }
    return(con)
  }else{
    cat("Error: Provide a list of alignments.")
    return(invisible(NULL))
  }
}

#Normal Mode analyssis
igem_RMSIP<-function(modes.1=NULL,modes.2=NULL,Name,lab="",plot=T){#NMA or PCA
  if(!is.null(modes.1)&&!is.null(modes.2)){
    try(  r<-bio3d::rmsip(modes.1,modes.2))
    if(plot){
      FileName=paste0(Name,"_rmsip.png",sep="")
      png(filename = FileName , width = 1500, height = 780)
      plot(r,xlab=lab[2],ylab=lab[1])
      dev.off()
    }
    return(r)
  }else{
    cat("Error: Provide pca, nma or matrix.")
    return(invisible(NULL))
  }
}  

igem_PDB_Trim<-function(PDB=NULL,chain="A"){
  if(!is.null(PDB)&&(chain!="")){
    try(pdb.full<-bio3d::read.pdb(PDB))
    try(pdb.open<-bio3d::trim.podb(pdb.full,atom.select(pdb.full,chain=chain)))
    return(pdb.open)  
  }
}

igem_nma_mode_visualization<-function(modes=NULL,number=NULL,Name="",view=T) {
  FileName=paste0(Name,"_nma|mode_visualization.pdb")
  if(try(a<-mktrj.nma(modes,mode=number,file=FileName))){
    if(view){view.modes(modes,mode=number)}
    return(a)
  }else{
    cat("Error: Provide more information")
  }
}

igem_nma_cross_cor<-function(PDB=NULL,Name="",plot=T,view=F) { #PDB is one chain
  if(try(cm<-bio3d::dccm(modes))){
    if(plot){
      FileName=paste0(Name,"_nma_cross_cor.png")
      png(filename = FileName , width = 1500, height = 780)
      print(plot(cm,sse=PDB,contour=F,col.regions=bwr.colors(20),at=seq(-1,1,0.1)))
      dev.off()    
    }
    if(view){
      bio3d::view.dccm(cm,PDB) ###PDBof chain
    }
    return(cm)  
  }else{
    cat("Error: Provide better information.")
    return(invisible(NULL))
  }
}

igem_fluct_deform<-function(modes=NULL,Name="",SEQ=NULL,save=F){#SEQ:count number of modes
  #deformation
  if(try(defe<-bio3d::deformation.nma(modes))){
    defsums<-rowSums(defe$ei[,1:3])
    #fluctuation
    try(flucts<-fluct.nma(modes,mode.inds=SEQ))
    if(save){
      FileName<-paste0(Name,"_deformation.pdb")
      write.pdb(pdb=NULL,xyz=modes$xyz,file=FileName,b=defsums)
      FileName<-paste0(Name,"_fluctuation.pdb")
      write.pdb(pdb=NULL,xyz=modes$xyz,file=FileName,b=flucts)
    }
    return(list(Deformation=defsums,Fluctuation=flucts)) 
  }else{
    cat("Error: Provide modes.")
    return(invisible(NULL))
  }
}

igem_overlap<-function(PDB.1=NULL,PDB.2=NULL,modes=NULL,plot=T,Name,marked=3){#PDB is sub unit !!!! different statesof sub unit for example closed/open
  if(try(aln<-bio3d::struct.aln(PDB.1,PDB.2,max.cycles=0))){
    pdb.2$xyz<-aln$xyz
    ##difference vector
    if((try(a.inds<-bio3d_core_analysis(pdb=PDB.1,Name="",save_core=c("black","pink","red"),plot_inds=F,save_inds=F)[2]))&&(!is.null(modes))){
      xyz<-rbind(pdb.1$xyz[aln$a.inds$xyz],pdb.2$xyz[aln$a.inds$xyz])
      diff<-bio3d::difference.vector(xyz)
      oa<-bio3d::overlap(modes,diff)
      
      if(plot){
        check<-NULL    
        FileName<-paste0(Name,"_overlap.png")
        png(filename = FileName , width = 1500, height = 780)
        print({plot(oa$overlap,type="h",xlab="Mode index",ylab="Squared overlap",ylim=c(0,1))
               points(oa$overlap,col=1)
               lines(oa$overlap.cum,type="b",col=2,cex=0.5)
               for (i in 1:marked){
                 len<-length(modes$frequencies) ##anzahl dermodes
                 x<-sort(modes$frequencies,partial=len-i)[n-i]#x größter wert nach x-1
                 #number<-colnames(modes$frequencies[i])##number of mode
                 text(x+0.5,oa$overlap[x],c(paste0("Mode ", x,sep=""),adj=0))
               } })
        #text(c(1,5)+0.5,oa$overlap[c(1,5)],c("mode1","mode5"),adj=0)=)
        dev.off()
        
        #squared overlap
        FileName<-paste0(Name,"_overlap_squared.png")
        png(filename = FileName , width = 1500, height = 780)
        print(plot(oa$overlap.cum,type="b",ylim=c(0,1),ylab="Squared overlap (cum)",xlab="Mode index",cex.lab=1.4,cex.axis=1.2,lwd=2))
        dev.off()
      }  
      return(oa)
    }
  }else{
    cat("Error: Provide two pdb files.")
    return(invisible(NULL))
  }
}

igem_multiple_pdb<-function(PDBs=NULL,ids=NULL,seq.ident=F,Name=""){#PDBs as vector
  #ids=c("4b7t_A", "2exm_A", "1opj_A", "4jaj_A", "1a9u_A", "1tki_A", "1phk_A", "1csn_A", "1lp4_A")  example
  if((is.null(ids))&&(!is.null(PDBs))){    
    #download
    raw.files<-bio3d::get.pdb(ids,path="raw_pdbs")
    files<-bio3d::pdbsplit(raw.files,ids) #characte vector
    #alignment
    pdbs<-bio3d::pdbaln(files)     
  }else{
    pdbs<-bio3d::pdbaln(PDBs)    
  }
  if(seq.ident&&!is.null(pdbs)){
    FileName<-paste0(Name,"_nma|multiple_seqidentity.txt",sep="")
    sink(FileName)
    cat("Sequence Identity") 
    cat(summary(c(seqidentity(pdbs))))      
  } 
  sink()
  return(pdbs)
}   

#one pds
igem_nma_pdbs<-function(pdb=NULL,ids=NULL,Name,keep=3,print=F,save=F,plot=F){
  if(bio3d::is.pdb(pdb)){
    modes.calpha<-bio3d::nma(pdb,ff="calpha",keep=num.modes)
    modes.anm<-bio3d::nma(pdb,ff="anm",keep=num.modes)
    modes.pfanm<-bio3d::nma(pdb,ff="pfanm",keep=num.modes)
    modes.reach<-bio3d::nma(pdb,ff="reach",keep=num.modes)
    modes.sdenm<-bio3d::nma(pdb,ff="sdenm",keep=num.modes)
    Matrix=(data.frame(calpha=modes.calpha,anm=modes.anm,pfnam=modes.pfanm,reach=modes.reach,sdenm=modes.sdenm))
    if(print){
      for(i in length(Matrix)){
        print(paste0(colnames(M)[i],sep=""))
        print(M[,i])      
      } 
    }
    if(save){
      FileName<-paste0(Name,"_nma|modes.txt",sep="")
      sink(FileName)
      for(i in length(Matrix)){
        cat(paste0(colnames(Matrix)[i],sep=""))
        cat("\n")
        cat(Matrix[,i])      
      } 
      sink()
    }
    if(plot){
      if(!is.null(ids)){
        for(i in length(Matrix)){
          
          print(paste0(colnames(Matrix)[i],sep=""))
          print(Matrix[,i])   
          FileName<-paste0(Name,"_nma|modes_",colnames(Matrix)[i],".png",sep="")
          
          png(filename = FileName , width = 1500, height = 780)
          print({plot(Matrix[,i],pdbs,type="h") 
                 legend("topleft",legend=ids,col=seq(1,nrow(Matrix[,i]$fluctuations)),lty=1)})
          dev.off()   
        }
      }else{
        cat("Error: Provide ids.")
        return(invisible(NULL))
      }             
    }  
    #}  
    return(as.matrix(Matrix))
  }else{
    cat("Error: Provide pdb file.")
  }
}

igem_multiple_crosscor<-function(modes=NULL,Name="",plot=F,cutoff.sims=9,cutoff.cij=0){
  #cross cormatrix
  if(try(cij<-dccm(modes))){
    dimnames(cij$all.dccm)<-list(NULL,NULL,ids)
    cij.all<-bio3d::dccm.mean(cij$all.dccm,cutoff.sims=cutoff.sims,cutoff.cij=cutoff.cij)
    
    if(plot){
      FileName=paste0(Name,"_nma|multiple_crosscor_residue.png",sep="")
      png(filename = FileName , width = 1500, height = 780)
      print(bio3d::plot.dccm(cij$all.dccm)  )
      dev.off()
      
      FileName=paste0(Name,"_nma|multiple_crosscor_consensus.png",sep="")
      png(filename = FileName , width = 1500, height = 780)
      print(bio3d::plot.dccm(cij.all,main="Consensus Residue Cross Correlation")  )
      dev.off()   
    }
    return(data.frame(cij,cij.all))  
  }else{
    cat("Error: Provide a mode.")
    return(invisible(NULL))
  }
}

#use one mode!!!
igem_multiple_dynamics<-function(pdbs=NULL,modes=NULL,ids=NULL,state=NULL,Name="",save=T){
  if(!is.null(pdbs)&&(!is.null(modes)&&(!is.null(ids)))){
    #find gaps
    gaps.res<-bio3d::gap.inspect(pdbs$ali)
    gaps.pos<-bio3d::gap.inspect(pdbs$xyz)
    if(state==NULL){state<-ids}
    #plot fluct
    if(save){
      FileName=paste0(Name,"_nma|multiple_fluctuation.png",sep="")
      png(filename = FileName , width = 1500, height = 780)
      plot(modes,col=col,pdbs=pdbs)
      legend("left",lty=c(1,1),lwd=c(2,2),col=col,legend=ids)
      dev.off() 
    }
    if(save){
      #heatmap clustering dendrogram
      FileName=paste0(Name,"_nma|multiple_dynamic_heatmap_rmsip.png",sep="")
      png(filename = FileName , width = 1500, height = 780)
      print(heatmap((1-modes$rmsip),labRow=state,labCol=ids,symm=TRUE))
      dev.off()
    }
    
    #pairwise rmsd
    try(rmsd.map<-bio3d::rmsd(pdbs$xyz,a.inds=gaps.pos$f.inds,fit=T))
    
    if(save){
      FileName=paste0(Name,"_nma|multiple_dynamic_heatmap_rmsd.png",sep="")
      png(filename = FileName , width = 1500, height = 780)
      print(heatmap(rmsd.map,labRow=state,labCol=ids,symm=T))
      dev.off()
    }
    return(list(modes$rmsip,rmsd.map))  
  }else{
    cat("Error: Provide more information")
    return(invisible(NULL))
  }
} 
